from datetime import datetime
import os
from src.config import AUDIO_DIR, PUBLIC_BASE_DIR, SUBTITLE_DIR, VIDEO_DIR
from src.database.dao.generated_video_dao import log_error, log_info
from src.database.dao_factory import DAOFactory
from src.modules.video_merger import VideoMerger
from src.modules.whoosh_processor import Util

class ToolController:
    def __init__(self):
        self.dao_factory = DAOFactory.get_instance()
        self.video_merger = VideoMerger(
            startupinfo=Util.get_startupinfo(),
            transition_duration=1.0,
            transition_effect="fade",
        )

    def upload_audio(self, audio_file, group_id, order, subtitle_file=None, target_directory=None, meta_data=None):
        """
        上传音频文件到指定目录
        
        :param audio_file: 上传的音频文件对象
        :param group_id: 分组ID
        :param order: 排序值
        :param subtitle_file: 上传的字幕文件对象（可选）
        :param target_directory: 目标目录，如果为None则使用默认目录
        :param meta_data: 额外元数据
        :return: 处理结果
        """
        if audio_file is None:
            return {"success": False, "message": "没有提供文件"}
        
        try:
            # 获取原始文件名并确保安全
            original_filename = audio_file.filename
            # 移除可能的路径注入字符
            safe_filename = os.path.basename(original_filename)
            
            # 如果未指定目标目录，使用系统默认目录
            if not target_directory:
                target_directory = AUDIO_DIR
            
            if not meta_data:
                meta_data = {}
            
            # 确保目录存在
            if not os.path.exists(target_directory):
                os.makedirs(target_directory, exist_ok=True)
                
            # 生成带时间戳的文件名，避免重名
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            filename, ext = os.path.splitext(safe_filename)
            new_filename = f"{filename}_{timestamp}{ext}"
            audio_path = os.path.join(target_directory, new_filename)
            
            # 保存音频文件
            audio_file.save(audio_path)
            
            # 处理字幕文件（如有）
            subtitle_path = None
            if subtitle_file:
                subtitle_filename = os.path.basename(subtitle_file.filename)
                subtitle_name, subtitle_ext = os.path.splitext(subtitle_filename)
                new_subtitle_name = f"{subtitle_name}_{timestamp}{subtitle_ext}"
                subtitle_path = os.path.join(target_directory, new_subtitle_name)
                subtitle_file.save(subtitle_path)
            
            # 使用新的DAO创建记录
            result = self.dao_factory.get_uploaded_file_dao().create_audio_with_subtitle(
                audio_path=audio_path,
                audio_filename=new_filename,
                subtitle_path=subtitle_path,
                subtitle_filename=new_subtitle_name if subtitle_file else None,
                group_id=group_id,
                order=order,
                meta_data=meta_data,
                status="active"
            )
            
            if not result.get("success", False):
                raise Exception(result.get("message", "创建文件记录失败"))
            
            log_info(f"音频文件已上传到: {audio_path}")
            return {
                "success": True,
                "message": "文件上传成功",
                "audio_path": audio_path,
                "subtitle_path": subtitle_path,
                "file_id": result.get("audio_file", {}).get("id")
            }
            
        except Exception as e:
            error_message = f"上传音频文件时出错: {e}"
            log_error(error_message)
            return {"success": False, "message": error_message}

    def upload_video(self, video_file, video_type, meta_data=None):
        """处理视频文件上传请求"""
        if not video_file:
            return {"success": False, "message": "未提供视频文件"}, 400
        
        try:
            filename = video_file.filename
            target_directory = os.path.join(VIDEO_DIR, video_type)
            # 确保目标目录存在
            if not os.path.exists(target_directory):
                os.makedirs(target_directory, exist_ok=True)
            # 保存视频文件到目标目录
            video_path = os.path.join(target_directory, filename)
            video_file.save(video_path)
            self.dao_factory.get_uploaded_file_dao().create_video(
                video_path=video_path,
                video_filename=filename,
                video_type=video_type,
                meta_data=meta_data
            )
            return {
                "success": True,
                "message": "视频文件上传成功",
                "video_path": video_path,
                "filename": filename,
            }
        except Exception as e:
            return {"success": False, "message": str(e)}, 500
        
        
    def delete_media(self, file_id):
        """删除指定ID的媒体文件"""
        try:
            result = self.dao_factory.get_uploaded_file_dao().delete(file_id)
            if result:
                return {"success": True, "message": "文件删除成功"}
            else:
                return {"success": False, "message": "文件删除失败或文件不存在"}
        except Exception as e:
            log_error(f"删除文件时出错: {e}")
            return {"success": False, "message": str(e)}
        
        
    def set_default_video(self, video_id, video_type):
        """设置指定视频为默认视频"""
        try:
            result = self.dao_factory.get_uploaded_file_dao().set_default_video(video_id, video_type)
            if result:
                return {"success": True, "message": "默认视频设置成功"}
            else:
                return {"success": False, "message": "设置默认视频失败或视频不存在"}
        except Exception as e:
            log_error(f"设置默认视频时出错: {e}")
            return {"success": False, "message": str(e)}
        
        
    def burn_subtitles(self, video_path, subtitle_path, 
                       output_path,
                       ):
        """
        将字幕烧录到视频中
        
        :param video_path: 视频文件路径
        :param subtitle_path: 字幕文件路径
        :param output_path: 输出视频路径
        :return: 处理结果
        """
        try:
            if not os.path.exists(video_path):
                return {"success": False, "message": "视频文件不存在"}
            if not os.path.exists(subtitle_path):
                return {"success": False, "message": "字幕文件不存在"}
            
            # 调用视频合并模块进行烧录
            result = self.video_merger.burn_subtitles_to_video(
                video_path=video_path,
                subtitle_path=subtitle_path,
                output_path=output_path,
                )
            if result.get("success", False):
                return {
                    "success": True,
                    "message": "字幕烧录成功",
                    "output_path": output_path
                }
            else:
                return {"success": False, "message": result.get("message", "烧录失败")}
        except Exception as e:
            log_error(f"烧录字幕时出错: {e}")
            return {"success": False, "message": str(e)}
        
    def upload_subtitle(self, subtitle_file):
        """
        上传字幕文件到指定目录
        
        :param subtitle_file: 上传的字幕文件对象
        :return: 处理结果
        """
        try:
            target_directory = SUBTITLE_DIR
            filename = subtitle_file.filename
            if not os.path.exists(target_directory):
                os.makedirs(target_directory, exist_ok=True)
            path = os.path.join(target_directory, filename)
            subtitle_file.save(path)
            log_info(f"上传字幕文件: {filename} 到目录: {target_directory}")
            self.dao_factory.get_uploaded_file_dao().create_subtitle_with_unique_path(
                subtitle_path=path,
                subtitle_filename=filename,
            )
            return path
        except Exception as e:
            raise Exception(f"上传字幕文件失败: {str(e)}")
 
 
    def update_subtitle_videos_mappings(self, mappings):
        """
        更新字幕与视频的映射关系
        
        :param mappings: 字幕与视频的映射列表
        :return: 处理结果
        """
        try:
            self.dao_factory.get_uploaded_file_dao().update_subtitle_videos_mappings(mappings)
        except Exception as e:
            log_error(f"更新字幕与视频映射关系时出错: {e}")
            raise Exception(f"更新字幕与视频映射关系失败: {str(e)}")
        
        
    def get_subtitle_list(self, page, page_size, query):
        """
        获取字幕列表
        
        :param page: 页码
        :param page_size: 每页大小
        :param query: 查询条件
        :return: 字幕列表和总数
        """
        try:
            subtitles, total_count = self.dao_factory.get_uploaded_file_dao().get_subtitle_list(page, page_size, query)
            total_pages = (total_count + page_size - 1) // page_size  # 计算总页数
            for subtitle in subtitles:
                video_paths = subtitle.get("meta_data", {}).get("video_paths", [])
                subtitle["video_paths"] = [
                    path.replace(PUBLIC_BASE_DIR, "\\public") for path in video_paths
                ]
            return {
                "items": subtitles,
                "pagination": {
                    "page": page,
                    "page_size": page_size,
                    "total_count": total_count,
                    "total_pages": total_pages
                }
            }
        except Exception as e:
            log_error(f"获取字幕列表时出错: {e}")
            raise Exception(f"获取字幕列表失败: {str(e)}")
        
    def get_media_by_id(self, file_id):
        """
        根据文件ID获取媒体文件信息
        
        :param file_id: 文件ID
        :return: 媒体文件信息
        """
        return self.dao_factory.get_uploaded_file_dao().get_by_id(file_id, True)